package config

import (
	"fmt"
	"github.com/sirupsen/logrus"
	"github.com/streadway/amqp"
	"log"
	"net/url"
	"strings"
	"sync"
)

var rabbitInstance *RabbitWrap
var once2 sync.Once // 确保初始化只执行一次的同步工具

type RabbitWrap struct {
	Conn    *amqp.Connection
	Channel *amqp.Channel
}

// ‘聊天消息数据’交换机
const MessageExchange = "chat_message_exchange"

// ‘通知消息’交换机
const NotifyExchange = "chat_notify_exchange"

// 创建结构体实例
var MqDataSave = MqInfo{
	Exchange:   MessageExchange,
	QueueName:  "chat_message_save_queue",
	RoutingKey: "chat.message.save",
}

var MqDataOffline = MqInfo{
	Exchange:   MessageExchange,
	QueueName:  "chat_message_offline_queue",
	RoutingKey: "chat.message.offline",
}

var MqStatusUpdate = MqInfo{
	Exchange:   MessageExchange,
	QueueName:  "chat_message_status_queue",
	RoutingKey: "chat.message.status",
}

var MqInfoArray = []MqInfo{
	MqDataSave, MqDataOffline, MqStatusUpdate,
}

type MqInfo struct {
	// 队列名称
	QueueName string
	// 交换机
	Exchange string
	// routing Key
	RoutingKey string
}

func InitMQ(props *RabbitMQProperties) {
	once2.Do(func() {
		username := url.QueryEscape(props.Username)
		password := url.QueryEscape(props.Password)

		//const MQURL = "amqp://guest:guest@localhost:5672/"
		var mqUrl = strings.ReplaceAll(fmt.Sprintf("amqp://%s:%s@%s/", username, password, props.Endpoint), " ", "")
		logrus.Debug("RabbitMQ 连接地址 ", mqUrl)

		//创建rabbitmq连接
		conn, err := amqp.Dial(mqUrl)
		if err != nil {
			log.Fatal("MqInfo 连接失败. ", err)
		}
		//创建Channel
		channel, err := conn.Channel()
		if err != nil {
			log.Fatal("MqInfo 创建Channel失败. ", err)
		}

		rabbitInstance = &RabbitWrap{
			Conn:    conn,
			Channel: channel,
		}

		// 1.定义聊天消息交换机（Direct模式），根据RoutingKey到不同的Queue
		channel.ExchangeDeclare(
			MessageExchange,
			"direct",
			true,
			false,
			false,
			false,
			nil,
		)

		// 2.定义Queue：聊天消息队列、离线消息队列、状态消息队列
		for _, mqinfo := range MqInfoArray {
			//定义Queue
			channel.QueueDeclare(mqinfo.QueueName, true, false, false, false, nil)
			channel.QueueBind(mqinfo.QueueName, mqinfo.RoutingKey, mqinfo.Exchange, false, nil)
		}
	})
}

func GetMqChannel() *amqp.Channel {
	return rabbitInstance.Channel
}
func Get() {

}
